//
// SdlGraph.cpp for nibbler in /home/titouan/Dropbox/Code/nibbler-epitech-2017/inc
//
// Made by creach titouan
// Login   <titouan@epitech.net>
//
// Started on  Thu Mar 13 17:09:10 2014 creach titouan
// Last update Mon Mar 24 13:52:27 2014 Titouan Creach
//

#include <iostream>
#include <dlfcn.h>
#include <stdexcept>
#include "exceptions.hpp"
#include "Graph.hpp"

Graphics::Graphics(int, char**, int w, int h) :
    _w(w),
    _h(h),
    _font(0)
{
  if (SDL_Init(SDL_INIT_VIDEO) == -1)
    throw LibraryInteralError("SDL", SDL_GetError());
  if (TTF_Init() == -1)
    throw LibraryInteralError("SDL_TTF", SDL_GetError());
}

void Graphics::loadImages(const std::map<IGraph::Image, std::string> &loadMap)
{
  std::map<IGraph::Image, std::string>::const_iterator it;

  for (it = loadMap.begin() ; it != loadMap.end() ; ++it)
    {
      _imgMap[it->first] = IMG_Load((it->second).c_str());
      if (_imgMap[it->first] == 0)
        {
          throw ImageNotFoundExceptions(it->second);
        }
    }
}

void Graphics::loadFont(const std::string &fontPath)
{
  _font = TTF_OpenFont(fontPath.c_str(), 25);
  if (_font == 0)
    throw FontNotFoundExceptions(fontPath);
}

void Graphics::writeText(char r, char g, char b, const std::string &text, int x, int y)
{
  SDL_Color c;
  SDL_Surface *t;
  SDL_Rect pos;

  c.r = r;
  c.g = g;
  c.b = b;
  pos.x = x;
  pos.y = y;

  t = TTF_RenderText_Blended(_font, text.c_str(), c);
  SDL_BlitSurface(t, NULL, _screenHandle, &pos);
}

Point Graphics::getTextSize(const std::string &text) const
{
  Point p;
  SDL_Color c = {0, 0, 0, 0};
  SDL_Surface *t;

  t = TTF_RenderText_Blended(_font, text.c_str(), c);

  p.x = t->w;
  p.y = t->h;

  return (p);
}

void Graphics::pause()
{
  SDL_Event ev;

   while (1)
     {
       SDL_WaitEvent(&ev);
       if (ev.type == SDL_QUIT || ev.type == SDL_KEYDOWN)
         return;
       SDL_Flip(_screenHandle);
     }
}

void Graphics::clearScreen(char r, char g, char b)
{
  Uint32 color;

  color = SDL_MapRGB(_screenHandle->format, r, g, b);
  SDL_FillRect(_screenHandle, 0, color);
}

void Graphics::openWindow()
{
  _screenHandle = SDL_SetVideoMode(_w, _h ,25, SDL_HWSURFACE | SDL_DOUBLEBUF);
  if (_screenHandle == 0)
    throw LibraryInteralError("SDL", SDL_GetError());
}

void Graphics::display()
{
  SDL_Flip(_screenHandle);
}

void Graphics::drawBlock(IGraph::Image img, int x, int y)
{
  SDL_Rect pos;
  std::map<IGraph::Image, SDL_Surface*>::iterator it;

  it = _imgMap.find(img);
  pos.x = x;
  pos.y = y;
  SDL_BlitSurface(it->second, NULL, _screenHandle, &pos);
}

void Graphics::wait(unsigned int d) const
{
  SDL_Delay(d);
}

Graphics::~Graphics()
{
  //liberer les ressources du jeu

  std::map<IGraph::Image, SDL_Surface*>::iterator it;
  for (it = _imgMap.begin() ; it != _imgMap.end() ; ++it)
    {
      SDL_FreeSurface(it->second);
    }

  TTF_CloseFont(_font);
  SDL_Quit();
  TTF_Quit();
}

IGraph::Event Graphics::getNextEvent()
{
  while (SDL_PollEvent(&e))
    {
      if (e.type == SDL_QUIT)
        return IGraph::QUIT;

      if (e.type == SDL_KEYDOWN)
        {
          if (e.key.keysym.sym == SDLK_ESCAPE)
            return IGraph::QUIT;
          if (e.key.keysym.sym == SDLK_UP)
            return IGraph::UP;
          if (e.key.keysym.sym == SDLK_DOWN)
            return IGraph::DOWN;
          if (e.key.keysym.sym == SDLK_LEFT)
            return IGraph::LEFT;
          if (e.key.keysym.sym == SDLK_RIGHT)
            return IGraph::RIGHT;
        }
    }
  return IGraph::NONE;
}

unsigned int Graphics::getCurrentTime() const
{
  return SDL_GetTicks();
}
